package com.yincheng.oes.business.service.impl;

import com.yincheng.oes.business.consist.ResultCodeEnum;
import com.yincheng.oes.business.dao.StudentDao;
import com.yincheng.oes.business.dao.StudentPaperDao;
import com.yincheng.oes.business.model.dto.StudentPaperDTO;
import com.yincheng.oes.business.model.dto.StudentSearchResultDTO;
import com.yincheng.oes.business.model.entity.StudentDO;
import com.yincheng.oes.business.model.entity.StudentPaperDO;
import com.yincheng.oes.business.model.query.StudentPaperReq;
import com.yincheng.oes.business.model.query.StudentSearchReq;
import com.yincheng.oes.business.model.result.BusinessResult;
import com.yincheng.oes.business.service.StudentService;
import com.yincheng.oes.business.util.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @Author: yangsy
 * @Contact: 446948434@qq.com
 * @Date: 2021/8/27 19:07
 * @Version: 1.0
 * @Description:
 */
@Service
public class StudentServiceImpl implements StudentService {
    /**
     * 日志
     */
    private static final Logger logger = LogManager.getLogger(StudentServiceImpl.class);

    /**
     * 单线程的线程池
     */
    private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    private static final String UN_EXPORT_STATUS = "0";
    private static final String EXPORTED_STATUS = "1";
    private static final String UN_EXPORTED_STATUS_VAL = "未导出";
    private static final String EXPORTED_STATUS_VAL = "已导出";

    private static final Integer MAX_STUDENT_SIZE = 10;

    private final StudentDao studentDao;

    private final StudentPaperDao studentPaperDao;

    public StudentServiceImpl(StudentDao studentDao, StudentPaperDao studentPaperDao) {
        this.studentDao = studentDao;
        this.studentPaperDao = studentPaperDao;
    }

    public List<StudentSearchResultDTO> searchStudents(StudentSearchReq req) {
        logger.debug("start searchStudents, req is {}", req);
        List<StudentSearchResultDTO> studentSearchResultList = new ArrayList<>();
        if (Objects.isNull(req) || StringUtils.isEmpty(req.getReqValue())) {
            logger.error("searchStudents param invalid");
            return studentSearchResultList;
        }
        List<StudentDO> studentsByAccount = studentDao.searchStudentByAccount(req.getReqValue());
        List<StudentDO> studentsByName = studentDao.searchStudentByName(req.getReqValue());
        Set<StudentDO> students = new HashSet<>();
        if (CollectionUtils.isNotEmpty(studentsByAccount)) {
            students.addAll(studentsByAccount);
        }
        if (CollectionUtils.isNotEmpty(studentsByName)) {
            students.addAll(studentsByName);
        }
        studentSearchResultList = students.stream().sorted(Comparator.comparing(StudentDO::getUserName)).map(e -> {
            StudentSearchResultDTO studentSearchResult = new StudentSearchResultDTO();
            studentSearchResult.setUserId(e.getUserId());
            studentSearchResult.setUserName(e.getUserName());
            studentSearchResult.setAccount(e.getAccount());
            return studentSearchResult;
        }).limit(MAX_STUDENT_SIZE).collect(Collectors.toList());
        logger.debug("after searchStudents, studentSearchResultList are {}", studentSearchResultList);
        return studentSearchResultList;
    }

    public Pair<Integer, List<StudentPaperDTO>> getListByParam(StudentPaperReq req) {
        logger.debug("start searchStudentPaper, req is {}", req);
        List<StudentPaperDTO> studentPapers = new ArrayList<>();
        if(Objects.isNull(req) || StringUtils.isEmpty(req.getUserId())){
            return Pair.of(0, studentPapers);
        }
        Page page = req.getPage();
        int total = studentPaperDao.countByParam(req);
        page.setTotal(total);
        List<StudentPaperDO> studentPaperDOS = studentPaperDao.searchStudentPapersByParam(req);
        if(CollectionUtils.isEmpty(studentPaperDOS)){
            return Pair.of(total, studentPapers);
        }
        studentPapers = getStudentPaperS(studentPaperDOS);
        return Pair.of(total, studentPapers);
    }

    private List<StudentPaperDTO> getStudentPaperS(List<StudentPaperDO> studentPaperDOS) {
        List<StudentPaperDTO> studentPapers;
        studentPapers = studentPaperDOS.stream().filter(Objects::nonNull).map(e -> {
            StudentPaperDTO studentPaperDTO = new StudentPaperDTO();
            studentPaperDTO.setPaperName(e.getPaperName());
            studentPaperDTO.setPaperResultId(e.getPaperResultId());
            if (StringUtils.equals(e.getExportStatus(), EXPORTED_STATUS)) {
                studentPaperDTO.setExportStatusVal(EXPORTED_STATUS_VAL);
            } else {
                studentPaperDTO.setExportStatusVal(UN_EXPORTED_STATUS_VAL);
            }
            return studentPaperDTO;
        }).collect(Collectors.toList());
        return studentPapers;
    }

    public BusinessResult searchStudentPaper(String userId) {
        logger.debug("start searchStudentPaper, userId is {}", userId);
        BusinessResult businessResult;
        List<StudentPaperDTO> studentPapers = new ArrayList<>();
        if (StringUtils.isEmpty(userId)) {
            logger.warn("searchStudentPaper param invalid, userId is {}", userId);
            businessResult = new BusinessResult(ResultCodeEnum.SUCCESS);
            businessResult.setData(studentPapers);
            return businessResult;
        }
        List<StudentPaperDO> studentPaperDOS = studentPaperDao.searchStudentPapers(userId);
        if (CollectionUtils.isEmpty(studentPaperDOS)) {
            logger.debug("searchStudentPapers is null, userId is {}", userId);
            businessResult = new BusinessResult(ResultCodeEnum.SUCCESS);
            businessResult.setData(studentPapers);
            return businessResult;
        }
        studentPapers = getStudentPaperS(studentPaperDOS);
        logger.debug("after searchStudentPapers, studentPapers are {}, userId is {}", studentPapers, userId);
        businessResult = new BusinessResult(ResultCodeEnum.SUCCESS);
        businessResult.setData(studentPapers);
        return businessResult;
    }




}
